<template>
  <div>
    <el-row :gutter="20">
      <el-col :span="12">
        <el-card shadow="hover">
          <template #header>
            <div class="clearfix">
              <span>基础信息</span>
            </div>
          </template>
          <div class="info">
            <div class="info-image" @click="showDialog">
              <el-avatar :size="100" :src="userStore.avatarUrl" />
              <span class="info-edit">
                <i class="el-icon-lx-camerafill"></i>
              </span>
            </div>
            <div class="info-name">{{ profile.nickname }}</div>
            <div class="info-desc">{{ profile.desc }}</div>
            <div class="info-role">权限： {{ roleName }}</div>
          </div>
        </el-card>
      </el-col>
      <el-col :span="12">
        <el-card shadow="hover">
          <template #header>
            <div class="clearfix">
              <span>账户编辑</span>
            </div>
          </template>
          <el-form label-width="90px" :rules="rules" :model="profile" ref="profileFormRef" status-icon>
            <el-form-item label="用户名：" prop="nickname">
              <el-input v-model="profile.nickname"></el-input>
            </el-form-item>
            <el-form-item label="个人网站：">
              <el-input v-model="profile.website"></el-input>
            </el-form-item>
            <el-form-item label="个人简介：">
              <el-input v-model="profile.desc"></el-input>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="onProfileSubmit(profileFormRef)">保存</el-button>
            </el-form-item>
          </el-form>
        </el-card>
      </el-col>
    </el-row>
    <el-row style="margin-top: 20px">
      <el-col :span="24">
        <el-card shadow="hover">
          <template #header>
            <div class="clearfix">
              <span>修改密码</span>
            </div>
          </template>
          <el-form label-width="100px" :rules="rules" :model="password" ref="passwordFormRef" status-icon>
            <el-form-item label="旧密码：" prop="old">
              <el-input type="password" v-model="password.old"></el-input>
            </el-form-item>
            <el-form-item label="新密码：" prop="new">
              <el-input type="password" v-model="password.new"></el-input>
            </el-form-item>
            <el-form-item label="确认密码：" prop="confirm">
              <el-input type="password" v-model="password.confirm"></el-input>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="onPasswordSubkmit(passwordFormRef)">保存</el-button>
              <el-button type="primary" @click="resetFields(passwordFormRef)">重置</el-button>
            </el-form-item>
          </el-form>
        </el-card>
      </el-col>
    </el-row>
    <el-dialog title="裁剪图片" v-model="dialogVisible" width="600px">
      <vue-cropper
        ref="cropper"
        :src="imgSrc"
        :ready="cropImage"
        :zoom="cropImage"
        :cropmove="cropImage"
        style="width: 100%; height: 400px"
      ></vue-cropper>

      <template #footer>
        <span>
          <el-button class="crop-demo-btn" type="primary"
            >选择图片
            <input class="crop-input" type="file" name="image" accept="image/*" @change="setImage" />
          </el-button>
          <el-button type="primary" @click="saveAvatar">上传并保存</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts" name="user">
  import { reactive, ref, onBeforeMount } from 'vue'
  import { sessionCache } from '@/utils/cache'
  import { updatePwdRequest, updateProfileRequest, getUserProfileRequest, uploadUserAvatarRequest } from '@/network/api/user-api'
  import type { Ipassword, Iprofile } from './interface'
  import type { FormInstance, FormRules } from 'element-plus'
  import VueCropper from 'vue-cropperjs'
  import notification from '@/utils/notification'
  import base64ToFile from '@/utils/base64ToFile'
  import 'cropperjs/dist/cropper.css'
  import useUserStore from '@/store/user'
  const userStore = useUserStore()
  let { id, roleName } = sessionCache.getCache('userInfo')
  const profile = reactive<Iprofile>({
    nickname: '',
    website: '',
    desc: '',
  })
  const password = reactive<Ipassword>({
    old: '',
    new: '',
    confirm: '',
  })
  const imgSrc = ref<string>()
  const cropImg = ref<string>()
  const dialogVisible = ref(false)
  const cropper = ref<InstanceType<typeof VueCropper>>()
  const profileFormRef = ref<FormInstance>()
  const passwordFormRef = ref<FormInstance>()
  const rules = reactive<FormRules>({
    nickname: [
      { required: true, message: '用户名最好不要设置为空~', trigger: 'blur' },
      { min: 1, max: 15, message: '长度保持在1-15个字符之间~  ', trigger: 'blur' },
    ],
    old: [{ required: true, message: '请填写您现在的密码~', trigger: 'blur' }],
    new: [
      { required: true, message: '请填写您的新密码~', trigger: 'blur' },
      { min: 5, max: 15, message: '密码长度保持在5-15个字符之间~  ', trigger: 'blur' },
    ],
    confirm: [
      { required: true, message: '请再填写一次新密码，确保两次的密码一致~', trigger: 'blur' },
      { min: 5, max: 15, message: '密码长度保持在5-15个字符之间~  ', trigger: 'blur' },
    ],
  })

  onBeforeMount(async () => {
    const result = await getUserProfileRequest(id)
    const { user_nickname, user_describe, website, avatar_url } = result.result
    profile.nickname = user_nickname
    profile.desc = user_describe
    profile.website = website
    userStore.changeAvatar(avatar_url)
  })

  const showDialog = () => {
    dialogVisible.value = true
    imgSrc.value = userStore.avatarUrl
  }

  const setImage = (e: any) => {
    const file = e.target.files[0]
    if (!file.type.includes('image/')) {
      return
    }
    const reader = new FileReader()
    reader.onload = (event: any) => {
      dialogVisible.value = true
      imgSrc.value = event.target.result
      cropper.value && cropper.value.replace(event.target.result)
    }
    reader.readAsDataURL(file)
  }

  const cropImage = () => {
    cropImg.value = cropper.value.getCroppedCanvas().toDataURL()
  }

  // 上传头像
  const saveAvatar = async () => {
    userStore.avatarUrl = cropImg.value
    dialogVisible.value = false
    const file = base64ToFile(cropImg.value!, Date.now() + '')
    const formData = new FormData()
    formData.append('avatar', file)
    const result = await uploadUserAvatarRequest(formData)
    const { avatar_url } = result.result
    sessionCache.setCache('avatar', avatar_url + '?' + Math.random())
    userStore.changeAvatar(avatar_url + '?' + Math.random())
    notification.success(result.msg)
  }

  // 基本信息
  const onProfileSubmit = async (formEl: FormInstance | undefined) => {
    if (!formEl) return
    await formEl.validate(async (valid, fields) => {
      if (valid) {
        const result = await updateProfileRequest(profile)
        userStore.changeNickname(profile.nickname)
        sessionCache.setCache('nickname', profile.nickname)
        notification.success(result.msg)
      } else {
        console.log('error submit!', fields)
      }
    })
  }

  // 更改密码
  const onPasswordSubkmit = async (formEl: FormInstance | undefined) => {
    if (!formEl) return
    await formEl.validate(async (valid, fields) => {
      if (valid) {
        if (password.new !== password.confirm) return notification.warning('两次密码输入不一致！')
        const result = await updatePwdRequest(password)
        notification.success(result.msg)
        // 重置表单
        passwordFormRef.value!.resetFields()
      } else {
        notification.error('error submit!')
      }
    })
  }

  // 重置表单
  const resetFields = (formEl: FormInstance | undefined) => {
    if (!formEl) return
    formEl.resetFields()
  }
</script>

<style scoped>
  .el-card {
    height: 350px;
  }

  .info {
    text-align: center;
    padding: 35px 0;
  }

  .info-image {
    position: relative;
    margin: auto;
    width: 100px;
    height: 100px;
    background: #f8f8f8;
    border: 1px solid #eee;
    border-radius: 50px;
    overflow: hidden;
  }

  .info-edit {
    display: flex;
    justify-content: center;
    align-items: center;
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background: rgba(0, 0, 0, 0.5);
    opacity: 0;
    transition: opacity 0.3s ease;
  }

  .info-edit i {
    color: #eee;
    font-size: 25px;
  }

  .info-image:hover .info-edit {
    opacity: 1;
  }

  .info-name {
    margin: 15px 0 10px;
    font-size: 24px;
    font-weight: 500;
    color: #262626;
  }

  .info-role {
    margin: 12px;
    font-size: 24px;
    font-weight: 500;
    color: #262626;
  }

  .crop-demo-btn {
    position: relative;
  }

  .crop-input {
    position: absolute;
    width: 100px;
    height: 40px;
    left: 0;
    top: 0;
    opacity: 0;
    cursor: pointer;
  }
</style>
